package org.tio.showcase.websocket.server;

import java.nio.ByteBuffer;
import java.util.Objects;

import com.alibaba.fastjson.JSON;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.tio.core.Tio;
import org.tio.core.ChannelContext;
import org.tio.http.common.HttpRequest;
import org.tio.http.common.HttpResponse;
import org.tio.showcase.dbUtil.RedisUtil;
import org.tio.websocket.common.WsRequest;
import org.tio.websocket.common.WsSessionContext;
import org.tio.websocket.server.handler.IWsMsgHandler;

/**
 * @author tanyaowu
 * 2017年6月28日 下午5:32:38
 */
public class ShowcaseWsMsgHandler implements IWsMsgHandler {
	private static Logger log = LoggerFactory.getLogger(ShowcaseWsMsgHandler.class);

	public static final ShowcaseWsMsgHandler me = new ShowcaseWsMsgHandler();

	private ShowcaseWsMsgHandler() {

	}

	/**
	 * 握手时走这个方法，业务可以在这里获取cookie，request参数等
	 */
	@Override
	public HttpResponse handshake(HttpRequest request, HttpResponse httpResponse, ChannelContext channelContext) throws Exception {
		String clientip = request.getClientIp();
		String userId = request.getParam("userId");
		Tio.bindUser(channelContext, userId);
		//channelContext.setUserid(userId);
		log.info("收到来自{}的ws握手包\r\n{}", clientip, request.toString());
		return httpResponse;
	}

	/**
	 * 握手，连接成功后处理方法
	 * @param httpRequest
	 * @param httpResponse
	 * @param channelContext
	 * @throws Exception
	 * @author tanyaowu
	 */
	@Override
	public void onAfterHandshaked(HttpRequest httpRequest, HttpResponse httpResponse, ChannelContext channelContext) throws Exception {
	    // 用户在线缓存,登录成功就缓存一个小时
        RedisUtil.setnx("Online:user_"+channelContext.userid,"这里可以缓存用户信息");
        RedisUtil.expire("Online:user_"+channelContext.userid,60*60);
		// 绑定到群组，后面会有群发
		WsMsgSend.bindUserToGroup(channelContext,channelContext.userid);
		// 获取用户离线时的消息，并重新推送消息
		WsMsgSend.Online_message_push(channelContext);
		int count = Tio.getAll(channelContext.tioConfig).getObj().size();

		// 以下可用于其他业务逻辑处理，例如用户上线，提醒管理员
//		String msg = "{name:'admin',message:'" + channelContext.userid + " 进来了，共【" + count + "】人在线" + "'}";
//		//用tio-websocket，服务器发送到客户端的Packet都是WsResponse
//		WsResponse wsResponse = WsResponse.fromText(msg, ShowcaseServerConfig.CHARSET);
//		//群发
//		Tio.sendToGroup(channelContext.tioConfig, Const.GROUP_ID, wsResponse);
	}

	/**
	 * 字节消息（binaryType = arraybuffer）过来后会走这个方法
	 */
	@Override
	public Object onBytes(WsRequest wsRequest, byte[] bytes, ChannelContext channelContext) throws Exception {
		String text = new String(bytes, "utf-8");
		log.info("收到byte消息:{},{}", bytes, text);
		ByteBuffer buffer = ByteBuffer.allocate(bytes.length);
		buffer.put(bytes);
		return buffer;
	}

	/**
	 * 当客户端发close flag时，会走这个方法
	 */
	@Override
	public Object onClose(WsRequest wsRequest, byte[] bytes, ChannelContext channelContext) throws Exception {
		Tio.remove(channelContext, "receive close flag");
		return null;
	}

	/*
	 * 字符消息（binaryType = blob）过来后会走这个方法
	 */
	@Override
	public Object onText(WsRequest wsRequest, String text, ChannelContext channelContext) throws Exception {
		WsSessionContext wsSessionContext = (WsSessionContext) channelContext.get();
		HttpRequest httpRequest = wsSessionContext.getHandshakeRequest();//获取websocket握手包
		if (log.isDebugEnabled()) {
			log.debug("握手包:{}", httpRequest);
		}

//		log.info("收到ws消息:{}", text);

		if (Objects.equals("心跳内容", text)) {
			return null;
		}
		String type = JSON.parseObject(text).getString("type");
		switch (type){
			case Const.SINGLE_CHAT_ID:  //单聊，私聊
				WsMsgSend.pointToPoint(channelContext,text);
				break;
			case Const.GROUP_CHAT_ID:  //群聊，一对多发送消息
				WsMsgSend.oneToMany(channelContext,text);
				break;
//			case SendMessage.TYPE_SAY:  //聊天模式
//				messageHandler.message(message, channel);
//				break;
//			case SendMessage.TYPE_FILE:  //文件上传模式
//				messageHandler.fileMessage(message, channel);
//				break;
		}

		return null;
	}

}
